﻿using System;
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
    using UnityEditor;

 #endif
using System.Collections.Generic;
using Assets.Scripts.Util;
using Object = UnityEngine.Object;

public class UISelectObjectPath : MonoBehaviour 
{
    public enum SelectType
    {
        selectByPath,
        selectByObject,
    }
    public enum LoadToType
    {
        self, //default to add to this gameobject;
        target,//set parent to target;
        world, //add to world (parent is null)
    }
    [HideInInspector]
    public string objectPath = "";
    [HideInInspector]
    public string objectCDPath = "";
    [HideInInspector]
    public string objectGUID="";
    [HideInInspector]
    public Object selectObj = null;
    [HideInInspector]
    public bool canLoadForScene = false;
    [HideInInspector]
    public SelectType selectType = SelectType.selectByPath;
    [HideInInspector]
    public bool outsideABObject = false;
    [HideInInspector]
    public LoadToType loadToType = LoadToType.self;
    [HideInInspector]
    public GameObject targetGameObject;
    List<GameObject> spawnGoList = new List<GameObject>();
    /// <summary>
    /// if load type is not self,the gameobject's active or life is contact by loader;
    /// </summary>
    [HideInInspector]
    public bool autoContact = true;
    /// <summary>
    /// get resource object 
    /// </summary>
    /// <returns></returns>
    public Object GetResourceObject()
    {
        switch(selectType)
        {
            case SelectType.selectByObject:
                return selectObj;
            case SelectType.selectByPath:
                string path = ConvertPathToResourceLoadPath(objectPath);
                return Resources.Load(path);
            default:
                return null;
        }
    }
    /// <summary>
    /// if resource is gameobject，add this to the root
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    protected GameObject SpawnOneObject(string name)
    {
        //Profiler.BeginSample("UISelectObjectPath.SpawnOneObject");
        GameObject go = null;
        GameObject inst = null;
        switch (selectType)
        {
            case SelectType.selectByObject:
#if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    inst = PrefabUtility.InstantiatePrefab(selectObj) as GameObject;
                    if (null != inst)
                    {
                        Transform t = inst.transform;
                        GameObject parent = GetSpawnParentGo();
                        if (null != parent)
                            t.parent = parent.transform;
                        t.localPosition = Vector3.zero;
                        t.localRotation = Quaternion.identity;
                        t.localScale = Vector3.one;
                        if (loadToType == LoadToType.self)
                            PrefabUtility.DisconnectPrefabInstance(gameObject);
                        go = inst;
                    }
                    else
                    {
                       
                        {
                            #if USE_LOGWRAPPER 
 LogWrapper.LogError("the selectObj InstantiatePrefab Error!");  
 #endif
                        }
                    }
                }
                else
                {
                    go = NGUITools.AddChild(GetSpawnParentGo(), selectObj as GameObject);
                }
#else

                if(selectObj == null)
                {
                #if USE_LOGWRAPPER 
 LogWrapper.LogError("[UISlectObjectPath] SpawnOneObject == null 1");  
 #endif
                }

                go = NGUITools.AddChild( GetSpawnParentGo(),selectObj as GameObject);
                
 #endif
                break;
            case SelectType.selectByPath:
                if (string.IsNullOrEmpty(objectPath))
                {
                   
                    {
                        #if USE_LOGWRAPPER 
 LogWrapper.LogError("object path is empty!" , NGUITools.GetHierarchy(gameObject).Replace("\"", ""));  
 #endif
                    }
                    return null;
                }
                if (!Application.isPlaying)
                {
                    if(outsideABObject)
                    {
#if UNITY_EDITOR

                        // string[] abs = AssetBundleEditorUtility.getAssetBundleAssetsName(objectCDPath);
                        // List<string> assetNames = new List<string>();
                        // assetNames.AddRange(abs);
                        // string abName = assetNames[0];
                        // inst = AssetBundleEditorUtility.LoadAssetsFromName(objectCDPath, abName) as GameObject;
                        // go = NGUITools.AddChild(GetSpawnParentGo(), inst as GameObject);
                        // if (loadToType == LoadToType.self)
                        //     PrefabUtility.DisconnectPrefabInstance(gameObject);
#endif
                    }
                    else
                    {

#if UNITY_EDITOR

                        inst = PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(objectPath, typeof(Object))) as GameObject;
                        if (inst != null)
                        {
                            Transform t = inst.transform;
                            GameObject parent = GetSpawnParentGo();
                            if (null != parent)
                                t.parent = parent.transform;
                            t.localPosition = Vector3.zero;
                            t.localRotation = Quaternion.identity;
                            t.localScale = Vector3.one;
                            if (loadToType == LoadToType.self)
                                PrefabUtility.DisconnectPrefabInstance(gameObject);
                            go = inst;
                        }
                        else
                        {
#if USE_LOGWRAPPER 
 LogWrapper.LogError("the objectPath is Error:" + objectPath + " this object can't instance to add!-->" + NGUITools.GetHierarchy(gameObject).Replace("\"", ""));  
#endif
                        }


#endif
                    }

                }
                else
                {
                    string path = ConvertPathToResourceLoadPath(objectPath);
                        inst = UnityResources.Load(path) as GameObject;
                    if (null == inst)
                    {

#if USE_LOGWRAPPER 
 LogWrapper.LogError("the objectPath is Error:" , objectPath , " this object can't instance to add!-->" , NGUITools.GetHierarchy(gameObject).Replace("\"", ""));  
#endif
                    }
                    else
                        go = NGUITools.AddChild(GetSpawnParentGo(), inst as GameObject);
                }
                break;
        }
        if (null != go)
        {
#if UNITY_DEBUG
            go.name = name;

#endif
            switch (loadToType)
            {
                case LoadToType.self:
                    NGUITools.SetLayer(go, gameObject.layer);
                    break;
                case LoadToType.target:
                    NGUITools.SetLayer(go, targetGameObject.layer);
                    break;
            }
            spawnGoList.Add(go);
        }
        return go;

    }

    public List<GameObject> SpawnObjects(int num)
    {
       // int fff = Environment.TickCount;
        List<GameObject> goObjs = new List<GameObject>();
        GameObject inst = null;
        switch (selectType)
        {
            case SelectType.selectByObject:
#if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    for (int i = 0; i < num; i++)
                    {
                        inst = PrefabUtility.InstantiatePrefab(selectObj) as GameObject;
                        if (null != inst)
                        {
                            Transform t = inst.transform;
                            GameObject parent = GetSpawnParentGo();
                            if (null != parent)
                                t.parent = parent.transform;
                            t.localPosition = Vector3.zero;
                            t.localRotation = Quaternion.identity;
                            t.localScale = Vector3.one;
                            if (loadToType == LoadToType.self)
                                PrefabUtility.DisconnectPrefabInstance(gameObject);
                            goObjs.Add(inst);
                        }
                        else
                        {
#if USE_LOGWRAPPER 
 LogWrapper.LogError("the selectObj InstantiatePrefab Error!");  
#endif
                        }
                            
                    }
                }
                else
                {
                    for (int i = 0; i < num; i++)
                    {
                        GameObject go = NGUITools.AddChild(GetSpawnParentGo(), selectObj as GameObject);
                        goObjs.Add(go);
                    }
                }
#else
                for (int i = 0; i < num; i++)
                {
                    GameObject go = NGUITools.AddChild( GetSpawnParentGo(),selectObj as GameObject);
                    goObjs.Add(go);
                }

 #endif
                break;
            case SelectType.selectByPath:
                if (string.IsNullOrEmpty(objectPath))
                {
                    #if USE_LOGWRAPPER 
 LogWrapper.LogError("object path is empty!" + NGUITools.GetHierarchy(gameObject).Replace("\"", ""));  
 #endif
                    return goObjs;
                }
                if (!Application.isPlaying)
                {
#if UNITY_EDITOR
                    for (int i = 0; i < num; i++)
                    {
                        inst =
                            PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(objectPath, typeof (Object)))
                                as GameObject;
                        if (inst != null)
                        {
                            Transform t = inst.transform;
                            GameObject parent = GetSpawnParentGo();
                            if (null != parent)
                                t.parent = parent.transform;
                            t.localPosition = Vector3.zero;
                            t.localRotation = Quaternion.identity;
                            t.localScale = Vector3.one;
                            if (loadToType == LoadToType.self)
                                PrefabUtility.DisconnectPrefabInstance(gameObject);
                            goObjs.Add(inst);
                        }
                        else
                        {
 #if USE_LOGWRAPPER 
                            LogWrapper.LogError("the objectPath is Error:" , objectPath ,
                                                " this object can't instance to add!-->" ,
                                                NGUITools.GetHierarchy(gameObject).Replace("\"", ""));
#endif
                        }
                    }

 #endif      
                }
                else
                {
                    string path = ConvertPathToResourceLoadPath(objectPath);
                    inst = Resources.Load(path) as GameObject;
                    for (int i = 0; i < num; i++)
                    {
                        if (null == inst)
                        {
#if USE_LOGWRAPPER 
                            LogWrapper.LogError("the objectPath is Error:" , objectPath ,
                                                " this object can't instance to add!-->" ,
                                                NGUITools.GetHierarchy(gameObject).Replace("\"", ""));
#endif
                        }
                        else
                        {
                            GameObject go = NGUITools.AddChild(GetSpawnParentGo(), inst as GameObject);
                            goObjs.Add(go);
                        }
                    }
                }
                break;
        }
        if (null != goObjs && goObjs.Count > 0)
        {
            for (int i = 0; i < goObjs.Count; i++)
            {
                spawnGoList.Add(goObjs[i]);
#if UNITY_DEBUG
                goObjs[i].name = i.ToString();

#endif
                switch (loadToType)
                {
                    case LoadToType.self:
                        NGUITools.SetLayer(goObjs[i], gameObject.layer);
                        break;
                    case LoadToType.target:
                        NGUITools.SetLayer(goObjs[i], targetGameObject.layer);
                        break;
                }
            }
        }
        //
        //    LogWrapper.LogError("[性能测试][UISelectObjectPath][SpawnOneObject] LoadSyn: use ",
        //        (Environment.TickCount - fff));
        return goObjs;
    }

    public string GetResourceLoadPath()
    {
        return ConvertPathToResourceLoadPath(objectPath);
    }
    public virtual void Clear()
    {
        GameObject go;
        for (int i = spawnGoList.Count - 1; i >= 0; i--)
        {
            go = spawnGoList[i];
            if (null != go)
                NGUITools.DestroyImmediate(go);
        }
        spawnGoList.Clear();
    }
    GameObject GetSpawnParentGo()
    {
        switch (loadToType)
        {
            case LoadToType.self:
                return gameObject;
            case LoadToType.target:
                return targetGameObject;
            case LoadToType.world:
                return null;
        }
        return null;
    }
    void OnDestroy()
    {
        if (loadToType == LoadToType.self) return;
        if (!autoContact) return;
        Clear();
    }
    void OnEnable()
    {
        if (loadToType == LoadToType.self) return;
        if (!autoContact) return;
        GameObject go;
        for (int g = spawnGoList.Count - 1; g >= 0; g--)
        {
            go = spawnGoList[g];
            if (null != go)
                NGUITools.SetActive(go, true);
            else
                spawnGoList.Remove(go);
        }
    }
    void OnDisable()
    {
        if (loadToType == LoadToType.self ) return;
        if (!autoContact) return;
        GameObject go;
        for(int g = spawnGoList.Count - 1; g >= 0; g--)
        {
            go = spawnGoList[g];
            if (null != go)
                NGUITools.SetActive(go, false);
            else
                spawnGoList.Remove(go);
        }
    }

    public string GetABPathBySelectPath(string selectPath)
    {
        int index = selectPath.IndexOf(GetkeyFilterPath());
        string rePath = selectPath.Substring(index);
        rePath = rePath.Replace(GetkeyFilterPath(), "");
        return rePath;
    }
    public virtual string GetkeyFilterPath()
    {
        return string.Empty;
    }
    public virtual bool IsOpenABLoader()
    {
        return false;
    }
    /// <summary>
    /// 
    /// </summary>
    string ConvertPathToResourceLoadPath( string path )
    {
        if(outsideABObject)
        {
            return path;
        }
        else
        {
            string[] pathStr = path.Split('/');
            int pathStrLen = pathStr.Length;
            bool hasFind = false;
            string returnPath = "";
            for (int i = 0; i < pathStrLen; i++)
            {
                if (pathStr[i] == CommonConst.RESOURCE_NAME || pathStr[i] == CommonConst.RESOURCE_NAME.ToLower())
                {
                    hasFind = true;
                    continue;
                }
                if (hasFind)
                {
                    if (string.IsNullOrEmpty(returnPath))
                        returnPath = pathStr[i];
                    else
                        returnPath += "/" + pathStr[i];
                }
            }
            if (string.IsNullOrEmpty(returnPath))
            {
#if USE_LOGWRAPPER 
 LogWrapper.LogError("this is not resource url!");  
#endif
                return "";
            }
            else
                return returnPath.Split('.')[0];
        }
    }
}

